package lee.vioson.ebook.viewmodels

import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import lee.vioson.composecommon.base.mvi.Reducer
import lee.vioson.composecommon.base.mvi.UiEvent
import lee.vioson.composecommon.base.mvi.UiState
import lee.vioson.composecommon.isNotEmpty
import lee.vioson.ebook.data.AppContainer
import lee.vioson.remotedata.manager.AppConfigManager

/**
 *Author:viosonlee
 *Date:2023/6/10
 *DESCRIPTION:
 */
class LoginViewModel(
    private val appContainer: AppContainer
) : AppViewModel<LoginViewModel.State, LoginViewModel.Event>(appContainer.appEvent) {

    private val reducer = SubReducer(State())

    override val state: StateFlow<State>
        get() = reducer.state

    override fun sendEvent(event: Event) {
        reducer.sendEvent(event)
    }

    val appConfig = AppConfigManager.INTANCE.getInitAppConfig(appContainer.context)
        .catch { handleException(it) }
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000),null)

    private class SubReducer(initialState: State) :
        Reducer<State, Event>(initialState) {
        override fun reduce(oldState: State, event: Event) {
            when (event) {
                is Event.OnEmailChange -> {
                    setState(
                        oldState.copy(
                            email = event.email,
                            enable = event.email.isNotEmpty && oldState.password.isNotEmpty
                        )
                    )
                }

                is Event.OnPwdChange -> setState(
                    oldState.copy(
                        password = event.password,
                        enable = event.password.isNotEmpty && oldState.email.isNotEmpty
                    )
                )

                is Event.OnEmailError -> setState(oldState.copy(emailError = event.emailError))
                is Event.OnPwdError -> setState(oldState.copy(passwordError = event.pwdError))
            }
        }
    }

    fun login(email: String, password: String) =
        appContainer.loginRepository.login(appContainer.uniqueId, email, password, 1)
            .catch { handleException(it) }
            .onStart { showLoading() }
            .onCompletion { dismissLoading() }
            .onEach { }
            .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
            .launchIn(viewModelScope)

    sealed class Event : UiEvent {
        data class OnEmailChange(val email: String) : Event()
        data class OnPwdChange(val password: String) : Event()
        data class OnEmailError(val emailError: String) : Event()
        data class OnPwdError(val pwdError: String) : Event()
    }

    data class State(
        val email: String = "",
        val password: String = "",
        val emailError: String = "",
        val passwordError: String = "",
        val enable: Boolean = false
    ) : UiState
}

